import { Request, Response } from 'express';
import jwt from 'jsonwebtoken';
import crypto from 'crypto';
import { User, ADMIN_REGISTRATION_CODE } from '../models/user.model';
import { sendEmail } from '../utils/email';
import { Device } from '../models/device';
import { DeviceData } from '../models/deviceData.model';

const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';

export const authController = {
  // 用户注册
  async register(req: Request, res: Response): Promise<void> {
    try {
      const { username, email, password, adminCode } = req.body;

      // 验证必填字段
      if (!username || !email || !password) {
        res.status(400).json({ message: '请填写所有必填字段' });
        return;
      }

      // 检查用户是否已存在
      const existingUser = await User.findOne({
        $or: [
          { email: email.toLowerCase() },
          { username: username.toLowerCase() }
        ]
      }).maxTimeMS(5000); // 设置查询超时时间

      if (existingUser) {
        res.status(400).json({ message: '用户名或邮箱已被注册' });
        return;
      }

      // 创建新用户
      const user = new User({
        username: username.toLowerCase(),
        email: email.toLowerCase(),
        password,
        role: adminCode === ADMIN_REGISTRATION_CODE ? 'admin' : 'user',
      });

      await user.save();

      // 生成 JWT token
      const token = jwt.sign(
        { userId: user._id, role: user.role },
        JWT_SECRET,
        { expiresIn: '24h' }
      );

      res.status(201).json({
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role,
        },
        token,
      });
    } catch (error: any) {
      console.error('用户注册失败:', error);
      if (error.name === 'MongoServerError' && error.code === 11000) {
        res.status(400).json({ message: '用户名或邮箱已被注册' });
      } else if (error.name === 'ValidationError') {
        res.status(400).json({ message: '输入数据验证失败' });
      } else {
        res.status(500).json({ message: '注册失败，请稍后重试' });
      }
    }
  },

  // 用户登录
  async login(req: Request, res: Response): Promise<void> {
    try {
      const { email, password } = req.body;

      // 查找用户
      const user = await User.findOne({ email });
      if (!user) {
        res.status(401).json({ message: '邮箱或密码错误' });
        return;
      }

      // 验证密码
      const isMatch = await user.comparePassword(password);
      if (!isMatch) {
        res.status(401).json({ message: '邮箱或密码错误' });
        return;
      }

      // 生成 JWT token
      const token = jwt.sign(
        { userId: user._id, role: user.role },
        JWT_SECRET,
        { expiresIn: '24h' }
      );

      res.json({
        user: {
          id: user._id,
          username: user.username,
          email: user.email,
          role: user.role,
        },
        token,
      });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 重置密码请求
  async resetPassword(req: Request, res: Response): Promise<void> {
    try {
      const { email } = req.body;

      const user = await User.findOne({ email });
      if (!user) {
        res.status(404).json({ message: '用户不存在' });
        return;
      }

      // 生成重置令牌
      const token = crypto.randomBytes(32).toString('hex');
      user.resetPasswordToken = token;
      user.resetPasswordExpires = new Date(Date.now() + 3600000); // 1小时后过期
      await user.save();

      // 发送重置密码邮件
      const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}`;
      await sendEmail({
        to: user.email,
        subject: '重置密码',
        text: `请点击以下链接重置密码：${resetUrl}`,
        html: `<p>请点击以下链接重置密码：<a href="${resetUrl}">${resetUrl}</a></p>`,
      });

      res.json({ message: '重置密码链接已发送到您的邮箱' });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 设置新密码
  async setNewPassword(req: Request, res: Response): Promise<void> {
    try {
      const { token, password } = req.body;

      const user = await User.findOne({
        resetPasswordToken: token,
        resetPasswordExpires: { $gt: Date.now() },
      });

      if (!user) {
        res.status(400).json({ message: '重置密码链接无效或已过期' });
        return;
      }

      // 更新密码
      user.password = password;
      user.resetPasswordToken = undefined;
      user.resetPasswordExpires = undefined;
      await user.save();

      res.json({ message: '密码重置成功' });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 获取用户列表
  async getUsers(req: Request, res: Response): Promise<void> {
    try {
      const users = await User.find({}, { password: 0, resetPasswordToken: 0, resetPasswordExpires: 0 });
      res.json(users);
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 创建用户
  async createUser(req: Request, res: Response): Promise<void> {
    try {
      const { username, email, password, role } = req.body;

      // 检查用户是否已存在
      const existingUser = await User.findOne({ $or: [{ email }, { username }] });
      if (existingUser) {
        res.status(400).json({ message: '用户名或邮箱已被注册' });
        return;
      }

      // 创建新用户
      const user = new User({
        username,
        email,
        password,
        role: role || 'user',
      });

      await user.save();

      res.status(201).json({
        id: user._id,
        username: user.username,
        email: user.email,
        role: user.role,
      });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 删除用户
  async deleteUser(req: Request, res: Response): Promise<void> {
    try {
      const { userId } = req.params;

      // 不允许删除自己
      if (userId === req.user._id.toString()) {
        res.status(400).json({ message: '不能删除当前登录的用户' });
        return;
      }

      const user = await User.findByIdAndDelete(userId);
      if (!user) {
        res.status(404).json({ message: '用户不存在' });
        return;
      }

      res.json({ message: '用户删除成功' });
    } catch (error: any) {
      res.status(500).json({ message: error.message });
    }
  },

  // 获取用户数据统计
  async getUserData(req: Request, res: Response): Promise<void> {
    try {
      const { userId } = req.params;

      // 获取用户的设备数量
      const deviceCount = await Device.countDocuments({ userId });

      // 获取用户的数据点总数
      const totalDataPoints = await DeviceData.countDocuments({ userId });

      // 获取用户最后活动时间
      const lastActive = await DeviceData.findOne({ userId })
        .sort({ timestamp: -1 })
        .select('timestamp');

      res.json({
        deviceCount,
        totalDataPoints,
        lastActive: lastActive?.timestamp || new Date(),
      });
      return;
    } catch (error: any) {
      res.status(500).json({ message: error.message });
      return;
    }
  },

  // 更新用户密码
  async updatePassword(req: Request, res: Response): Promise<void> {
    try {
      const { currentPassword, newPassword } = req.body;
      const userId = req.params.userId || req.user._id;
      const isAdmin = req.user.role === 'admin';

      const user = await User.findById(userId);
      if (!user) {
        res.status(404).json({ message: '用户不存在' });
        return;
      }

      // 如果不是管理员，需要验证当前密码
      if (!isAdmin) {
        const isMatch = await user.comparePassword(currentPassword);
        if (!isMatch) {
          res.status(401).json({ message: '当前密码错误' });
          return;
        }
      }

      // 更新密码
      user.password = newPassword;
      await user.save();

      res.json({ message: '密码更新成功' });
      return;
    } catch (error: any) {
      res.status(500).json({ message: error.message });
      return;
    }
  },
}; 